{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "54bd32c5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-12-09T06:52:38.038063Z",
     "start_time": "2023-12-09T06:52:37.104554Z"
    },
    "execution": {
     "iopub.execute_input": "2024-05-02T10:55:36.232778Z",
     "iopub.status.busy": "2024-05-02T10:55:36.232330Z",
     "iopub.status.idle": "2024-05-02T10:55:46.731468Z",
     "shell.execute_reply": "2024-05-02T10:55:46.730538Z",
     "shell.execute_reply.started": "2024-05-02T10:55:36.232739Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy.fft as fft\n",
    "import cv2\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "from tqdm import tqdm\n",
    "import pandas as pd\n",
    "from cv2 import dct\n",
    "import imageio\n",
    "import quaternion as qt\n",
    "import imageio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "57572914-634d-4f37-a95f-efb42cd8fff5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-03T01:51:42.649892Z",
     "iopub.status.busy": "2024-05-03T01:51:42.649512Z",
     "iopub.status.idle": "2024-05-03T01:51:42.757280Z",
     "shell.execute_reply": "2024-05-03T01:51:42.756384Z",
     "shell.execute_reply.started": "2024-05-03T01:51:42.649869Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def image_hash(img_path,k):\n",
    "    img = processing(img_path)\n",
    "    feature = image_feature(img)\n",
    "    h_i = gen_hashing(feature,k)\n",
    "    return h_i\n",
    "\n",
    "def processing(img_path):\n",
    "    \"\"\"\n",
    "    input：图片的路径\n",
    "    output：处理后的RGB图片\n",
    "    \"\"\"\n",
    "    try:\n",
    "        img = cv2.imread(img_path)\n",
    "        x = img.shape[0]//2 # 高度\n",
    "        y = img.shape[1]//2 # 宽度\n",
    "        Min = x if x<y else y\n",
    "        cropped_image = img[x-Min:x+Min, y-Min:y+Min] # 裁剪图像\n",
    "        img = cv2.resize((cropped_image), (256,256), interpolation=cv2.INTER_LINEAR)\n",
    "    except:\n",
    "        img = imageio.mimread(img_path)\n",
    "        img = np.array(img)\n",
    "        img = img[0]\n",
    "        img = img[:, :, 0:3]\n",
    "        x = img.shape[0]//2 # 高度\n",
    "        y = img.shape[1]//2 # 宽度\n",
    "        Min = x if x<y else y\n",
    "        cropped_image = img[x-Min:x+Min, y-Min:y+Min] # 裁剪图像\n",
    "        img = cv2.resize((cropped_image), (256,256), interpolation=cv2.INTER_LINEAR)\n",
    "#     out = cv2.GaussianBlur(img, (3, 3),1.3) # 使用python自带的高斯低通滤波\n",
    "    kernel = np.ones((7,7), np.float32) / 49 # 平均滤波器\n",
    "    out = cv2.filter2D(img, -1 , kernel=kernel)  # 二维滤波器\n",
    "    out = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)\n",
    "    out = square2circle(out)\n",
    "    log_polar_img = cv2.logPolar(out, (out.shape[1] // 2, out.shape[0] // 2), 50, cv2.WARP_FILL_OUTLIERS)\n",
    "    return log_polar_img\n",
    "\n",
    "def square2circle(img):\n",
    "    \"\"\"\n",
    "    将最大内切圆以外的像素值置为0\n",
    "    img:array(512,512,3)\n",
    "    return:array(512,512,3)\n",
    "    \"\"\"\n",
    "    h,w,_ = img.shape\n",
    "    radius = int(min(h, w) / 2)  \n",
    "    mask = np.zeros((h, w,3), np.uint8)  \n",
    "    # 在mask中画出一个最大半径为radius的圆形区域\n",
    "    cv2.circle(mask, (w // 2, h // 2), radius, (255, 255, 255), -1)  \n",
    "    # 对原图和mask进行位运算，将圆形区域外的像素设置为0  \n",
    "    img_process = cv2.bitwise_and(img, mask)\n",
    "    return img_process\n",
    "\n",
    "def image_feature(img):\n",
    "    \"\"\"\n",
    "    iamge:(512,512,3)\n",
    "    return: array(512,512)\n",
    "    \"\"\"\n",
    "    rows,cols,_ = img.shape\n",
    "    quaternion_array = np.array([[np.quaternion(0, img[i,j,0],img[i,j,1],img[i,j,2]) for j in range(cols)] for i in range(rows)])\n",
    "    return np.fft.fftshift(fft2D(quaternion_array))\n",
    "    \n",
    "def exp_quaternion(u):\n",
    "    \"\"\"\n",
    "    四元数的指数运算\n",
    "    \"\"\"\n",
    "    # 手动计算四元数的模，并用它来规范化四元数\n",
    "    norm_u = np.abs(u)\n",
    "    v = u / (norm_u+(1e-80))\n",
    "    # 计算指数形式的指数运算\n",
    "    exponential_form = np.cos(norm_u) + v * np.sin(norm_u)\n",
    "    return exponential_form\n",
    "\n",
    "def fft1D(signal):\n",
    "    \"\"\"\n",
    "    signal:为一维的四元数序列\n",
    "    return:*\n",
    "    \"\"\"\n",
    "    # 定义单位纯四元数 u = ai + bj + ck，其中 |u| = 1\n",
    "    # 构建单位纯四元数\n",
    "    # 第一种四元数论文常用单位四元数\n",
    "    d1=3**(1/2)\n",
    "    u_lum = qt.quaternion(0, 1/d1, 1/d1, 1/d1)\n",
    "    # 第二种单位四元数\n",
    "    d2=68**(1/2)\n",
    "    u_perc=qt.quaternion(0, 0, -2/d2, 8/d2)\n",
    "    N = len(signal)\n",
    "    if N <= 1:\n",
    "        return signal\n",
    "    even = fft1D(signal[0::2])\n",
    "    odd = fft1D(signal[1::2])\n",
    "    #一维傅里叶变换公式\n",
    "    T = [exp_quaternion(-2*u_lum * np.pi * k / N) * odd[k] for k in range(N // 2)]\n",
    "    # T = [exp_quaternion(-2 * u_perc * np.pi * k / N) * odd[k] for k in range(N // 2)]\n",
    "    return np.concatenate([even + T, even - T])\n",
    "    \n",
    "def fft2D(image):\n",
    "    \"\"\"\n",
    "    image:四元数矩阵(256*256)\n",
    "    return:返回经过傅里叶变换后的四元数矩阵\n",
    "    \"\"\"\n",
    "    M, N = image.shape\n",
    "    if M <= 1 and N <= 1:\n",
    "        return image\n",
    "    # FFT along rows\n",
    "    rows = np.array([fft1D(row) for row in image])\n",
    "    # FFT along columns\n",
    "    cols = np.array([fft1D(col) for col in rows.T]).T\n",
    "    return cols\n",
    "\n",
    "def gen_hashing(feature_matrix,k):\n",
    "    \"\"\"\n",
    "    选取振幅系数矩阵中间偏左上的矩阵作为特征。\n",
    "    input:array (256,256)\n",
    "    output:list (x)\n",
    "    \"\"\"\n",
    "    coeff = []\n",
    "    start = int(feature_matrix.shape[0]/2-k//2+1)\n",
    "    for i in range(start,start+k):\n",
    "        for j in range(start,start+k):\n",
    "            coeff.append(feature_matrix[i][j].abs())\n",
    "    return np.array([1 if coeff[i] >= coeff[i+1] else 0 for i in range(len(coeff)-1)])\n",
    "    \n",
    "def dist_img(h1,h2):\n",
    "    return sum(np.abs(h1-h2))/len(h1)\n",
    "\n",
    "def dis_different_dir(path,k,des_path):\n",
    "    # 目录下图片之间的距离\n",
    "    if not os.path.exists(des_path):\n",
    "        os.makedirs(des_path)\n",
    "    dirs = os.listdir(path)\n",
    "    image_set_list = []\n",
    "    image_hashing_value_set = []\n",
    "    for i in tqdm(dirs,ncols = 50):\n",
    "    # for i in dirs:\n",
    "        image_hashing_value_set.append(image_hash(os.path.join(path, i),k))\n",
    "    for i in range(len(image_hashing_value_set)):\n",
    "        for j in range(i+1,len(image_hashing_value_set)):\n",
    "            image_set_list.append(dist_img(image_hashing_value_set[i],image_hashing_value_set[j]))\n",
    "    for i in range(int(np.ceil(len(image_set_list)/1000000))-1):\n",
    "        start = i*1000000\n",
    "        end = (i+1)*1000000\n",
    "        pd.DataFrame(image_set_list[start:end]).to_excel(os.path.join(des_path,f\"different_image_result_{i+1}.xlsx\"),index = False)\n",
    "    pd.DataFrame(image_set_list[end+1:]).to_excel(os.path.join(des_path,f\"different_image_result_{i+2}.xlsx\"),index = False)\n",
    "    return image_set_list,image_hashing_value_set\n",
    "\n",
    "def dis_similar_dir(path,k):\n",
    "    \"\"\"\n",
    "    path:相同图片每种操作的目录\n",
    "    k:选取中间多少元素作为哈希值\n",
    "    return:所有相同图片哈希距离的列表\n",
    "    \"\"\"\n",
    "    # 计算相同类型图片的距离\n",
    "    dir_rotation = os.listdir(path)\n",
    "    dis_similar = []\n",
    "    for i in dir_rotation:\n",
    "        if (os.path.splitext(i)[1] == \".bmp\") | (os.path.splitext(i)[1] == \".jpg\"):\n",
    "            h1 = image_hash(os.path.join(path, i),k)\n",
    "            dir_temp = os.path.join(path,os.path.splitext(i)[0])\n",
    "            for j in os.listdir(dir_temp):\n",
    "                h2 = image_hash(os.path.join(dir_temp,j),k)\n",
    "                dis_similar.append(dist_img(h1,h2))\n",
    "    return dis_similar\n",
    "\n",
    "def dir_dis_similar_dir(total_path,k,des_path):\n",
    "    \"\"\"\n",
    "    total_path:相同图片各种操作的根目录\n",
    "    des_path:存放结果的目录\n",
    "    return：存放每一种操作相同图片哈希距离的字典\n",
    "    \"\"\"\n",
    "    if not os.path.exists(des_path):\n",
    "        os.makedirs(des_path)\n",
    "    fold_each_attack = os.listdir(total_path)\n",
    "    dir_each_attack= {}\n",
    "    if not os.path.exists(os.path.join(des_path,\"similar_image_result\")):\n",
    "        os.makedirs(os.path.join(des_path,\"similar_image_result\"))\n",
    "    # total_path = os.path.join(total_path,\"similar_image_result\")\n",
    "    for i in tqdm(fold_each_attack,ncols = 50):\n",
    "        attack_path = os.path.join(total_path,i)\n",
    "        dir_each_attack[i] = dis_similar_dir(attack_path,k)\n",
    "        file_name = i + \".xlsx\"\n",
    "        pd.DataFrame(dir_each_attack[i]).to_excel(os.path.join(des_path,\"similar_image_result\",file_name),index = False)\n",
    "    return dir_each_attack\n",
    "\n",
    "def my_auc(image_similar, image_different):\n",
    "    from scipy import integrate\n",
    "    sum1 = len(image_similar)\n",
    "    sum2 = len(image_different)\n",
    "    tpr = []\n",
    "    fpr = []\n",
    "    threshold_max = (max(max(image_similar), max(image_different)))\n",
    "    for threshold in np.linspace(0,threshold_max,50):\n",
    "        tpr_number = len(image_similar[image_similar < threshold])\n",
    "        fpr_number = len(image_different[image_different < threshold])\n",
    "        tpr.append(tpr_number/sum1)\n",
    "        fpr.append(fpr_number/sum2)\n",
    "    return integrate.trapezoid(tpr,fpr)\n",
    "\n",
    "def stat_analysis(result_path):\n",
    "    \"\"\"\n",
    "    result_path:保存结果的路径\n",
    "    \"\"\"\n",
    "    dirs = os.listdir(result_path)\n",
    "    for i in dirs:\n",
    "        file_path = os.path.join(result_path, i)\n",
    "        if os.path.isdir (file_path):\n",
    "            for j in os.listdir(file_path):\n",
    "                xlsx_path = os.path.join(file_path,j)\n",
    "                data = pd.read_excel(xlsx_path,header = 0)[0]\n",
    "                print(f\"{j}的最小值：{min(data)}最大值：{max(data)}平均值：{np.mean(data)}\")\n",
    "        else:\n",
    "            xlsx_path = file_path\n",
    "            data = pd.read_excel(xlsx_path,header = 0)[0]\n",
    "            print(f\"{i}的最小值：{min(data)}最大值：{max(data)}平均值：{np.mean(data)}\")\n",
    "\n",
    "def auc_analysis(dir_path):\n",
    "    \"\"\"\n",
    "    dir_path:保存结果的路径\n",
    "    \"\"\"\n",
    "    similar_image_result_path = os.path.join(dir_path,\"similar_image_result\")\n",
    "    data_different =pd.Series()\n",
    "    for i in os.listdir(dir_path):\n",
    "        if not os.path.isdir(os.path.join(dir_path,i)):\n",
    "            print(os.path.join(dir_path,i))\n",
    "            temp = pd.read_excel(os.path.join(dir_path,i),header = 0)[0]\n",
    "            data_different = pd.concat((data_different,temp),axis=0)\n",
    "    similar_image_result_path_total = pd.Series()\n",
    "    for i in os.listdir(similar_image_result_path):\n",
    "        data_similar = pd.read_excel(os.path.join(similar_image_result_path,i),header = 0)[0]\n",
    "        similar_image_result_path_total= pd.concat((similar_image_result_path_total,data_similar),axis=0)\n",
    "        print(f\"{i}和不同图片的auc值：{my_auc(data_similar,data_different)}\")\n",
    "    print(f\"所有相同图片和不同图片 的auc值：{my_auc(similar_image_result_path_total,data_different)}\")\n",
    "\n",
    "def copy_dectection_result(query_path, test_path, k):\n",
    "    import glob\n",
    "    query_hash = []\n",
    "    test_hash = [] # 后 160 的结果是复制图像的结果\n",
    "    dist_set = []\n",
    "    for i in tqdm(os.listdir(query_path), ncols = 50):\n",
    "        query_hash.append(image_hash(os.path.join(query_path, i),k))\n",
    "    for i in tqdm(os.listdir(os.path.join(test_path, \"different_dataset\")), ncols =50):\n",
    "        test_hash.append(image_hash(os.path.join(test_path, \"different_dataset\", i),k))\n",
    "    for root, dirs, files in os.walk(os.path.join(test_path, \"copy_attack\")):\n",
    "        for file in tqdm(glob.glob(os.path.join(root, '*.[a-zA-Z]*')), ncols = 50):  # 你可以根据需要修改文件类型，例如 *.png, *.gif 等 \n",
    "            test_hash.append(image_hash(file, k))\n",
    "    print(len(test_hash), len(query_hash))\n",
    "    print(\"开始计算哈希距离\")\n",
    "    for i in tqdm(test_hash, ncols = 50):\n",
    "        for j in query_hash:\n",
    "            dist_set.append(dist_img(i, j))\n",
    "    pd.DataFrame(dist_set).to_excel(\"./复制检测结果/复制检测距离结果（1160）.xlsx\", index = False)\n",
    "    \n",
    "def P_R_result(path):\n",
    "    dist_set = np.array(pd.read_excel(path))\n",
    "    min_dist = min(dist_set)\n",
    "    max_dist = max(dist_set)\n",
    "    P = []\n",
    "    R = []\n",
    "    for threshold in np.linspace(min_dist, max_dist, 5):\n",
    "        diff_res = [1 if np.all(dist_set[i:i+10] > threshold) else 0 for i in np.arange(0, 9900, 10)]\n",
    "        copy_res = [1 if np.any(dist_set[i:i+10] <= threshold) else 0 for i in np.arange(9900, 11600, 10)]\n",
    "        # diff_res = [1 if np.all(dist_set[i:i+10] > threshold) else 0 for i in np.arange(0, 10000, 10)]\n",
    "        # copy_res = [1 if np.any(dist_set[i:i+10] <= threshold) else 0 for i in np.arange(10000, 11600, 10)]\n",
    "        TP = sum(copy_res)\n",
    "        # FN = 160 - TP\n",
    "        FN = 170 - TP\n",
    "        FP = 990 - sum(diff_res)\n",
    "        P.append(TP / (TP + FP))\n",
    "        R.append(TP / (TP + FN))\n",
    "    return np.linspace(min_dist, max_dist, 5), P, R\n",
    "\n",
    "def copy_dectection_result(dataset_path, k):\n",
    "    query_path = os.path.join(dataset_path, \"query_dataset\")\n",
    "    attack_path = os.path.join(dataset_path, \"test_dataset\", \"copy_attack\")\n",
    "    different_path = os.path.join(dataset_path, \"test_dataset\", \"different_dataset\")\n",
    "    result = pd.DataFrame()\n",
    "    different_hash = []\n",
    "    for j in os.listdir(different_path):\n",
    "        h2 = image_hash(os.path.join(different_path, j), k)\n",
    "        different_hash.append(h2)\n",
    "    for i in tqdm(os.listdir(query_path), ncols = 50):\n",
    "        temp = []\n",
    "        h1 = image_hash(os.path.join(query_path, i), k)\n",
    "        img_attack_path = os.path.join(attack_path, i.split(\".\")[0])\n",
    "        for j in os.listdir(img_attack_path):\n",
    "            h2 = image_hash(os.path.join(img_attack_path, j), k)\n",
    "            temp.append(dist_img(h1, h2))\n",
    "        for j in different_hash:\n",
    "            temp.append(dist_img(h1, j))\n",
    "        result[i] = temp\n",
    "    result.to_excel(\"./复制检测结果/第二次/result.xlsx\", index = False)\n",
    "    return result\n",
    "\n",
    "def cal_mAP(result_path):\n",
    "    result = pd.read_excel(result_path)\n",
    "    mAP = 0\n",
    "    for i in result:\n",
    "        now_10 = result[i][:10]\n",
    "        sorted_list = list(result[i])\n",
    "        sorted_list.sort()\n",
    "        max_10 = sorted_list[:10] # 这里是从小到大进行排序\n",
    "        mAP += cal_ap(now_10, max_10)\n",
    "    return mAP / 16\n",
    "\n",
    "def cal_ap(now_10, max_10):\n",
    "    AP = 0\n",
    "    bool_list = []\n",
    "    for i in now_10:\n",
    "        if i in max_10:\n",
    "            bool_list.append(1)\n",
    "        else:\n",
    "            bool_list.append(0)\n",
    "    for index, i in enumerate(bool_list):\n",
    "        AP += i * (sum(bool_list[:index+1]) / (index + 1))\n",
    "    return AP / len(now_10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2ae50bce-e078-4c53-867b-1d1c4fabb894",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-03T01:51:44.468625Z",
     "iopub.status.busy": "2024-05-03T01:51:44.468322Z",
     "iopub.status.idle": "2024-05-03T03:52:45.503046Z",
     "shell.execute_reply": "2024-05-03T03:52:45.502383Z",
     "shell.execute_reply.started": "2024-05-03T01:51:44.468604Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████| 16/16 [14:28<00:00, 54.29s/it]\n"
     ]
    }
   ],
   "source": [
    "result = copy_dectection_result(\"../new_data/copy_detection_dataset_2\", 15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0e5b2180-68ab-48ca-ad72-fb1530d53467",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-03T08:09:39.043793Z",
     "iopub.status.busy": "2024-05-03T08:09:39.043317Z",
     "iopub.status.idle": "2024-05-03T08:09:39.342956Z",
     "shell.execute_reply": "2024-05-03T08:09:39.342245Z",
     "shell.execute_reply.started": "2024-05-03T08:09:39.043765Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cal_mAP(\"./复制检测结果/第二次/result.xlsx\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "39acabdf-f7db-4550-bffd-808048edcd4f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-04-21T02:53:02.304401Z",
     "iopub.status.busy": "2024-04-21T02:53:02.302933Z",
     "iopub.status.idle": "2024-04-21T02:53:02.622951Z",
     "shell.execute_reply": "2024-04-21T02:53:02.621979Z",
     "shell.execute_reply.started": "2024-04-21T02:53:02.304333Z"
    }
   },
   "outputs": [],
   "source": [
    "# copy_dectection_result(\"../new_data/copy_detection_dataset/query_dataset/\", \"../new_data/copy_detection_dataset/test_dataset/\", 15)\n",
    "theshold, P, R = P_R_result(\"./复制检测结果/复制检测距离结果（1160）.xlsx\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ef16e318-6599-4bb2-a432-f3fedf050866",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-04-21T01:39:03.049095Z",
     "iopub.status.busy": "2024-04-21T01:39:03.047759Z",
     "iopub.status.idle": "2024-04-21T01:39:03.057414Z",
     "shell.execute_reply": "2024-04-21T01:39:03.055767Z",
     "shell.execute_reply.started": "2024-04-21T01:39:03.049024Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.09411764705882353, 0.5352941176470588, 0.7588235294117647, 0.8588235294117647, 0.9117647058823529, 0.9647058823529412, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]\n",
      "[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.96045197740113, 0.6390977443609023, 0.23676880222841226, 0.15030946065428824, 0.14667817083692838, 0.14655172413793102, 0.14655172413793102, 0.14655172413793102]\n"
     ]
    }
   ],
   "source": [
    "print(R)\n",
    "print(P)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "6620cd2e-c9b8-4203-998b-79b99e5e48f3",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-04-21T02:53:05.378103Z",
     "iopub.status.busy": "2024-04-21T02:53:05.377560Z",
     "iopub.status.idle": "2024-04-21T02:53:05.586769Z",
     "shell.execute_reply": "2024-04-21T02:53:05.585787Z",
     "shell.execute_reply.started": "2024-04-21T02:53:05.378072Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(R, P,  \"-o\")\n",
    "plt.grid()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "cd2110d4-dae4-45d6-a0fb-08635b952317",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-04-21T02:53:07.492761Z",
     "iopub.status.busy": "2024-04-21T02:53:07.491427Z",
     "iopub.status.idle": "2024-04-21T02:53:07.625599Z",
     "shell.execute_reply": "2024-04-21T02:53:07.624538Z",
     "shell.execute_reply.started": "2024-04-21T02:53:07.492691Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f83a7228850>]"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(theshold, P)\n",
    "plt.plot(theshold, R)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2db639b2-ef7f-4e81-83f0-32c3698e0e99",
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-03-30T13:09:48.597170Z",
     "iopub.status.idle": "2024-03-30T13:09:48.598329Z",
     "shell.execute_reply": "2024-03-30T13:09:48.597968Z",
     "shell.execute_reply.started": "2024-03-30T13:09:48.597931Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "dir_dis_similar_dir(\"../new_data/multiple_attack/\",15,\"./混合攻击结果/纯四元数版本_对数极坐标结果\")\n",
    "dis_different_dir(\"../new_data/different_image/\",15,\"./混合攻击结果/纯四元数版本_对数极坐标结果\")\n",
    "# stat_analysis(\"./新数据集结果/纯四元数版本_环形分区结果/\")\n",
    "auc_analysis(\"./混合攻击结果/纯四元数版本_环形分区结果/\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "image_qua",
   "language": "python",
   "name": "image_qua"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
